package com.yisen.dasan.interceptors;

import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yisen.dasan.config.Auth;
import com.yisen.dasan.dao.SafetyMapper;
import com.yisen.dasan.util.JWTUtils;
import com.yisen.dasan.util.ResultData;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.security.SignatureException;
import java.util.HashMap;
import java.util.Map;

/**
 * @AuthorList: LiuYiSen
 * @Date: 2020/11/28 22:56
 */
public class JWTInterceptors implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        Method method = ((HandlerMethod) handler).getMethod();
        Auth annotation = method.getAnnotation(Auth.class);
        if(annotation==null){
            return true;
        }else if(annotation.type()==0){
            String token = request.getHeader("token");
            ResultData resultData;
            try{
                DecodedJWT verify = JWTUtils.verify(token);// 验证令牌
                return true;
            }catch(SignatureVerificationException e){
                e.printStackTrace();
                resultData = new ResultData(false, 401, "无效签名", null);
            }catch(TokenExpiredException e){
                e.printStackTrace();
                resultData = new ResultData(false, 402, "token过期", null);
            }catch (Exception e){
                e.printStackTrace();
                resultData = new ResultData(false, 402, "token无效！", null);
            }
            String json = new ObjectMapper().writeValueAsString(resultData);
            response.setContentType("application/json;charset=UTF-8");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.getWriter().print(json);
            return false;
        }else if(annotation.type()==1){// 验证token正确性和用户和表单是否关联
            String id = request.getParameter("id");// 取表单id
            if (id==null || id.equals("")){
                id = request.getParameter("form_id");
            };
            if (id==null || id.equals("")){
                id = request.getParameter("formId");
            }
            WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
            SafetyMapper safetyMapper = applicationContext.getBean("safetyMapper", SafetyMapper.class);
            // 取用户id
            String token = request.getHeader("token");
            ResultData resultData;
            try{
                DecodedJWT verify = JWTUtils.verify(token);// 验证令牌
                int userId = Integer.parseInt(verify.getClaims().get("id").asString());// 取用户id
                Map<String, String> map = safetyMapper.verifyUserForm(userId, Integer.parseInt(id));
                if (map.size()==0){
                    String json = new ObjectMapper().writeValueAsString(new ResultData(false, 421, "您没有权限进行此操作", null));
                    response.setContentType("application/json;charset=UTF-8");
                    response.setHeader("Access-Control-Allow-Origin", "*");
                    response.getWriter().print(json);
                    return false;
                }
                return true;
            }catch(SignatureVerificationException e){
//                e.printStackTrace();
                System.out.println(e.getMessage());
                resultData = new ResultData(false, 401, "无效签名", null);
            }catch(TokenExpiredException e){
//                e.printStackTrace();
                System.out.println(e.getMessage());
                resultData = new ResultData(false, 402, "token过期", null);
            }catch (Exception e){
                System.out.println(e.getMessage());
                e.printStackTrace();
                resultData = new ResultData(false, 403, "token无效！", null);
            }
            String json = new ObjectMapper().writeValueAsString(resultData);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().print(json);
            response.setHeader("Access-Control-Allow-Origin", "*");
            return false;
        }
        return false;
    }
}
